package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishService;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.ibatis.annotations.Update;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/setmeal")
@Api(tags = "套餐相关接口")
public class SetmealController {


    @Autowired
    private SetmealService setmealService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private DishService dishService;

    //添加新的套餐
    @PostMapping
    @ApiOperation(value = "新增套餐接口")
    @CacheEvict(value = "setmealCache",allEntries = true)
    public R<String> save(@RequestBody SetmealDto setmealDto){

        setmealService.saveWithDish(setmealDto);

        return R.success("新增套餐成功");

    }

    //分页查询
    @GetMapping("/page")
    @ApiOperation(value = "套餐分页查询接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page",value = "页码",required = true),
            @ApiImplicitParam(name = "pageSize",value = "每页记录数",required = true),
            @ApiImplicitParam(name = "name",value = "套餐名称",required = false)
    })
    public R<Page> page(int page,int pageSize,String name){

        //构造分页查询器
        Page<Setmeal> pageInfo = new Page<>(page,pageSize);

        //构造SetmealDto构造器
        Page<SetmealDto> setmealDtoPage = new Page<>(page,pageSize);
        //构造条件构造器
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.like(name != null,Setmeal::getName,name);

        queryWrapper.orderByDesc(Setmeal::getUpdateTime);

        //分页查询
        setmealService.page(pageInfo,queryWrapper);

        //由于Setmeal中没有categoryName，只有categoryId，因此要重新封装
        //复制
        BeanUtils.copyProperties(pageInfo,setmealDtoPage,"records");

        //获取套餐列表
        List<Setmeal> records = pageInfo.getRecords();

        List<SetmealDto> list = records.stream().map((item) -> {
            //新建setmealDto对象
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(item, setmealDto);

            Long categoryid = item.getCategoryId();

            if(categoryid != null){
                Category category = categoryService.getById(categoryid);

                setmealDto.setCategoryName(category.getName());
            }

            return setmealDto;
        }).collect(Collectors.toList());

        setmealDtoPage.setRecords(list);
        return R.success(setmealDtoPage);
    }

    //根据id查询，修改时回显数据使用
    @GetMapping("/{id}")
    public R<SetmealDto> getById(@PathVariable  Long id){

        SetmealDto setmealDto = setmealService.getWithDish(id);

        return R.success(setmealDto);
    }

    //修改
    @PutMapping
    @CacheEvict(value = "setmealCache",allEntries = true)
    public R<String> update(@RequestBody SetmealDto setmealDto){

        setmealService.updateWithDish(setmealDto);

        return R.success("修改成功");
    }

    //单个删除或批量删除
    @DeleteMapping
    @ApiOperation(value = "套餐删除接口")
    @CacheEvict(value = "setmealCache",allEntries = true)
    public R<String> delete(@RequestParam List<String> ids){
        setmealService.deleteWithDish(ids);
        return R.success("删除成功");
    }

    //修改状态
    @PostMapping("/status/{statusValue}")
    @CacheEvict(value = "setmealCache",allEntries = true)
    public R<String> updateStatus(@PathVariable Integer statusValue,@RequestParam List<String> ids){

        UpdateWrapper<Setmeal> updateWrapper = new UpdateWrapper<>();

        updateWrapper.set("status",statusValue).in("id",ids);

        setmealService.update(updateWrapper);

        return R.success("修改成功");
    }

    //根据categoryId查询对应的套餐
    @GetMapping("/list")
    @ApiOperation(value = "套餐条件查询接口")
    @Cacheable(value = "setmealCache",key = "#setmeal.categoryId + '_' + #setmeal.status")
    public R<List<Setmeal>> list(Setmeal setmeal){

        //根据传入的categoryId查询

        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();

        Long categoryId = setmeal.getCategoryId();
        queryWrapper.eq(categoryId != null, Setmeal::getCategoryId,categoryId);

        //只查询status为1的setmeal
        queryWrapper.eq(setmeal.getStatus() != null, Setmeal::getStatus,setmeal.getStatus());

        List<Setmeal> list = setmealService.list(queryWrapper);

        return R.success(list);

    }

    //手机端调用,根据套餐id获取套餐中所有菜品
    @GetMapping("/dish/{id}")
    public R<List<DishDto>> getDIshById(@PathVariable  Long id){

        //先根据套餐id查询套餐菜品关系表，找出所有对应的关系

        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(id != null, SetmealDish::getSetmealId,id);

        List<SetmealDish> setmealDishes = setmealDishService.list(queryWrapper);

        //根据dishId查询菜品，并封装为DishDto，最后再整体封装为list

        List<DishDto> dishDtos = setmealDishes.stream().map((item) ->{
            DishDto dishDto = new DishDto();

            Dish dish = dishService.getById(item.getDishId());

            BeanUtils.copyProperties(dish,dishDto);

            dishDto.setCopies(item.getCopies());

            return dishDto;

        }).collect(Collectors.toList());


        return R.success(dishDtos);
    }

}
